import json
from datetime import datetime

import pandas as pd
from django.conf import settings
from django.contrib.auth import get_user_model
from django.http import HttpResponse
from django.shortcuts import reverse, render
from django.views import View
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_403_FORBIDDEN
from rest_framework.views import APIView

from apps.oaauth.models import OADepartment
from apps.oaauth.models import UserStatusChoices
from apps.oaauth.serializers import DepartmentSerializer
from oademo import celery
from utils import aeser
from .serializers import AddStaffSerializer, ActiveStaffSerializer, StaffUploadSerializer
from .tasks import send_mail_task

OAUser = get_user_model()
from django.http.response import JsonResponse
from urllib import parse
from rest_framework import generics, viewsets, mixins, status
from rest_framework import exceptions
from apps.oaauth.serializers import UserSerializer
from .paginations import StaffListPagination
from django.db import transaction


def send_active_email(request, email):
    aes = aeser.AESCipher(settings.SECRET_KEY)
    token = aes.encrypt(email)
    active_path = reverse('staff:active_staff') + "?" + parse.urlencode({'token': token})
    active_url = request.build_absolute_uri(active_path)
    message = f"请点击以下链接激活账号：{active_url}"
    subject = "激活账号"
    send_mail_task.delay(email, subject, message)
    # send_mail(f"激活账号", recipient_list=[email], message=message, from_email=settings.DEFAULT_FROM_EMAIL)


class DepartmentListView(ListAPIView):
    queryset = OADepartment.objects.all()
    serializer_class = DepartmentSerializer


class ActiveStaffView(View):
    def get(self, request):
        token = request.GET.get('token')
        response = render(request, "active.html")
        response.set_cookie('token', token)
        return response

    def post(self, request):
        try:
            aes = aeser.AESCipher(settings.SECRET_KEY)
            token = request.COOKIES.get('token')
            email = aes.decrypt(token)
            serializer = ActiveStaffSerializer(data=request.POST)
            if serializer.is_valid():
                form_email = serializer.validated_data.get('email')
                user = serializer.validated_data.get('user')
                if email != form_email:
                    return JsonResponse({'code': 400, "message": "邮箱错误"})
                user.status = UserStatusChoices.ACTIVED
                user.save()
                return JsonResponse({'code': 200, "message": "激活成功"})
            else:
                detail = list(serializer.errors.values())[0][0]
                return JsonResponse({'code': 400, "message": detail})
        except Exception:
            return JsonResponse({'code': 400, "message": "token错误"})


class StaffViewSet(generics.ListCreateAPIView,
                   viewsets.GenericViewSet,
                   mixins.ListModelMixin,
                   mixins.CreateModelMixin,
                   mixins.UpdateModelMixin,
                   ):
    queryset = OAUser.objects.all()
    pagination_class = StaffListPagination

    def get_serializer_class(self):
        if self.request.method in ['GET', 'PUT']:
            return UserSerializer
        else:
            return AddStaffSerializer

    def get_queryset(self):
        print(self.request.query_params)
        department_id = self.request.query_params.get('department_id')
        realname = self.request.query_params.get('realname')
        date_joined = self.request.query_params.getlist('date_joined[]')

        queryset = self.queryset
        user = self.request.user
        if user.department.name != "董事会":
            if user.uid != user.department.leader.uid:
                raise exceptions.PermissionDenied()
            else:
                queryset = queryset.filter(department_id=user.department_id)
                return queryset.all()
        else:
            if department_id:
                queryset = queryset.filter(department_id=department_id)
        if realname:
            queryset = queryset.filter(realname__icontains=realname)
        if date_joined:
            try:
                start_date = datetime.strptime(date_joined[0], '%Y-%m-%d')
                end_date = datetime.strptime(date_joined[1], '%Y-%m-%d')
                queryset = queryset.filter(date_joined__range=(start_date, end_date))
            except Exception:
                pass
        return queryset.all()

    def create(self, request, *args, **kwargs):
        serializer = AddStaffSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            email = serializer.validated_data.get('email')
            password = serializer.validated_data.get('password')
            realname = serializer.validated_data.get('realname')
            user = OAUser.objects.create_user(email=email, realname=realname, password=password)
            department = request.user.department
            user.department = department
            user.save()
            send_active_email(request, email)
            return Response(data={'detail': '添加成功'})
        else:
            return Response(data={'datail': list(serializer.errors.values())[0][0]}, status=HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return super().update(request, *args, **kwargs)


class TestCeleryView(APIView):
    def get(self, request):
        celery.debug_task.delay()
        return Response(data={'detail': 'ok'})


class StaffDownloadView(APIView):
    def get(self, request):
        pks = request.query_params.get('pks')
        try:
            pks = json.loads(pks)
        except Exception:
            return Response(data={'detail': 'pks参数错误'}, status=HTTP_400_BAD_REQUEST)
        try:
            current_user = request.user
            queryset = OAUser.objects
            if current_user.department.name != "董事会":
                if current_user.department.leader.uid != current_user.uid:
                    return Response(data={'detail': '权限不足'}, status=HTTP_403_FORBIDDEN)
                else:
                    queryset = queryset.filter(department_id=current_user.department_id)
            queryset = queryset.filter(pk__in=pks)
            result = queryset.values('email', 'realname', 'department__name', 'date_joined', "status")
            staff_df = pd.DataFrame(list(result))
            staff_df.rename(
                columns={"department__name": "部门", "date_joined": "入职时间", "status": "状态", 'realname': '姓名'},
                inplace=True)
            response = HttpResponse(content_type='application/xlsx')
            response['Content-Disposition'] = 'attachment; filename="员工信息.xlsx"'
            with pd.ExcelWriter(response) as writer:
                staff_df.to_excel(writer, sheet_name='员工信息')
            return response
        except Exception as e:
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)


class StaffUploadView(APIView):
    def post(self, request):
        serializer = StaffUploadSerializer(data=request.data)
        if serializer.is_valid():
            file = serializer.validated_data.get('file')
            current_user = request.user
            if current_user.department.name != "董事会" or current_user.department.leader_id != current_user.uid:
                return Response({"detail": "权限不足"}, status=status.HTTP_403_FORBIDDEN)
            staff_df = pd.read_excel(file)
            users = []
            for index, row in staff_df.iterrows():
                if current_user.department.name != "董事会":
                    department = current_user.department
                else:
                    try:
                        department = OADepartment.objects.get(name=row['部门'])
                        if not department:
                            return Response({"detail": "部门不存在"}, status=status.HTTP_400_BAD_REQUEST)
                    except Exception as e:
                        return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    user = OAUser(
                        email=row['邮箱'],
                        realname=row['姓名'],
                        department=department,
                        status=UserStatusChoices.UNACTIVE
                    )
                    user.set_password('123456')
                    users.append(user)
                except Exception as e:
                    return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
            try:
                with transaction.atomic():
                    OAUser.objects.bulk_create(users)
            except Exception as e:
                return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
            for user in users:
                send_active_email(request, user.email)
            return Response({"detail": "ok"})

        else:
            detail = list(serializer.errors.values())[0][0]
            return Response({"detail": detail}, status=status.HTTP_400_BAD_REQUEST)
